package com.alpha.schema;

import com.alpha.core.utils.Assert;
import com.alpha.schema.beans.*;
import lombok.extern.slf4j.Slf4j;

/**
 * 元数据校验工具
 *
 * @author chenruwan
 * @since 2022-01-01
 */
@Slf4j
public class SchemaChecker {
    private SchemaChecker() {
    }

    public static void check(Schema schema) {
        for (Choice each : schema.getChoices()) {
            checkChoice(each);
            Assert.isTrue(schema.getChoices().stream().filter(e -> each.getName().equals(e.getName())).count() == 1,
                    "choice " + each.getName() + " 不能重复");
        }
        for (Table table : schema.getTables()) {
            checkTable(table);
            Assert.isTrue(schema.getTables().stream().filter(e -> table.getName().equals(e.getName())).count() == 1,
                    "table " + table.getName() + " 不能重复");
        }
    }

    private static void checkChoice(Choice checked) {
        Assert.notEmpty(checked.getName(), "choice {} 的 name 属性不能为空", checked.getName());
        Assert.notEmpty(checked.getDesc(), "choice({}) 的 desc 属性不能为空", checked.getName());
        Assert.notEmpty(checked.getOptions(), "choice({}) 的 option 列表不能为空", checked.getName());
        for (Option option : checked.getOptions()) {
            Assert.notEmpty(option.getName(), "choice({}) option 的 name 属性不能为空", checked.getName());
            Assert.notEmpty(option.getCode(), "choice({}) option 的 code 属性不能为空", checked.getName());
            Assert.notEmpty(option.getValue(), "choice({}) option 的 value 属性不能为空", checked.getName());
        }
    }

    private static void checkTable(Table table) {
        Assert.notEmpty(table.getName(), "table 的 name 属性不能为空");
        Assert.notEmpty(table.getSingular(), "table({})  的 singular 属性不能为空", table.getName());
        Assert.notEmpty(table.getDesc(), "table({}) 的 desc 属性不能为空", table.getName());
        for (Field field : table.getFields()) {
            Assert.notEmpty(field.getName(), "table({}).field({}) 的 name 属性不能为空", table.getName(), field.getName());
            Assert.notEmpty(field.getType(), "table({}).field({}) 的 type 属性不能为空", table.getName(), field.getName());
            Assert.notEmpty(field.getDesc(), "table({}).field({}) 的 desc 属性不能为空", table.getName(), field.getName());
        }
        for (Foreign foreign : table.getForeigners()) {
            Assert.notEmpty(foreign.getKey(), "table {} 下 foreign 的 key 属性不能为空", table.getName());
            Assert.notEmpty(foreign.getReferences(), "table {} 下 foreign 的 references 属性不能为空", table.getName());
            Assert.notEmpty(foreign.getDesc(), "table {} 下 foreign 的 desc 属性不能为空", table.getName());
        }
        for (Relation relation : table.getRelations()) {
            Assert.notEmpty(relation.getTo(), "table({}) relation 的 to 属性不能为空", table.getName());
            Assert.notEmpty(relation.getDesc(), "table({}) relation 的 desc 属性不能为空", table.getName());
        }
    }
}
